package com.atguigu.gmall.index.controller;

import com.atguigu.gmall.common.bean.ResponseVo;
import com.atguigu.gmall.index.service.IndexService;
import com.atguigu.gmall.pms.entity.CategoryEntity;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping
public class IndexController {
    @Autowired
    IndexService indexService;
    @GetMapping({"/","index" , "index.html"})
    public String index(Model model){
        //查询categories：一级分类集合(parent_id为0的)     设置到request域中
        List<CategoryEntity> categoryEntities = indexService.queryLevelOneCategories();
        model.addAttribute("categories",categoryEntities);
        return "index";
    }
    /*
        1、@Controller+@ResponseBody
            @RestController
            接口方法返回的数据转为json响应
        2、@Controller
            接口方法返回的字符串如果没有以redirect:开始 就是转发
            以redirect:开始 重定向


     */
    //根据一级分类id查询二级和三级分类列表
    //http://api.gmall.com/index/cates/1
    //页面中的异步请求访问的是网关，网关并不知道/index/cates/1请求访问的是哪个服务
    @ResponseBody  //@Controller标注的Controller  接口方法返回的数据只有加了@ResponseBody注解才会转为json
    @GetMapping("/index/cates/{cid}")
    public ResponseVo<List<CategoryEntity>> levelTwoAndSubsCates(@PathVariable("cid")String cid){
        List<CategoryEntity> levelTwoAndSubsCates = indexService.levelTwoAndSubsCates(cid);
        return ResponseVo.ok(levelTwoAndSubsCates);
    }

    //秒杀接口： redis中有一个默认的num=0   并发访问5000次当前接口，没执行一次 redis中的num+1
    @ResponseBody
    @GetMapping("/index/testlock")
    public ResponseVo testLock(){
        try {
            indexService.testLock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return ResponseVo.ok();
    }

    /*
        信号量：
            配置资源数为1
            请求访问时获取到资源可以执行执行结束归还资源  获取不到的阻塞等待知道其他请求归还资源

     */
    @Autowired
    RedissonClient redissonClient;

    @ResponseBody
    @GetMapping("/index/testlock2")
    public ResponseVo testLock2(){
        //testLock2 的请求阻塞等待cdl 闭锁的值为0才继续执行
        RCountDownLatch cdl = redissonClient.getCountDownLatch("cdl");
        try {
            cdl.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("testLock2终于执行了....");
        return ResponseVo.ok();
    }
    @ResponseBody
    @GetMapping("/index/testlock3")
    public ResponseVo testLock3(){
        RCountDownLatch cdl = redissonClient.getCountDownLatch("cdl");
        try {
            cdl.countDown();//倒计数-1
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("testLock3执行了....");
        return ResponseVo.ok();
    }
//    @ResponseBody
//    @GetMapping("/index/testlock2")
//    public ResponseVo testLock2(){
//        //获取资源 如果获取成功继续执行
//        RSemaphore sempahore = redissonClient.getSemaphore("sempahore");
//        try {
////            sempahore.acquire();//阻塞等待获取资源
//            boolean b = sempahore.tryAcquire(3, TimeUnit.SECONDS);
//            if(!b){
//                //获取资源失败
//                return ResponseVo.fail("服务器繁忙");
//            }
//            System.out.println("testLock2执行了....."+new Date());
//            Thread.sleep(15000);
//            System.out.println("testLock2执行结束....."+new Date());
//            //归还资源
//            sempahore.release();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//            //归还资源
//            sempahore.release();
//        }
//        return ResponseVo.ok();
//    }
//
//    @ResponseBody
//    @GetMapping("/index/testlock3")
//    public ResponseVo testLock3(){
//        //获取资源 如果获取成功继续执行
//        RSemaphore sempahore = redissonClient.getSemaphore("sempahore");
//        try {
////            sempahore.acquire();//阻塞等待获取资源
//            boolean b = sempahore.tryAcquire(3, TimeUnit.SECONDS);
//            if(!b){
//                //获取资源失败
//                return ResponseVo.fail("服务器繁忙");
//            }
//            System.out.println("testLock3执行了....."+new Date());
//            //归还资源
//            sempahore.release();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//            //归还资源
//            sempahore.release();
//        }
//        return ResponseVo.ok();
//    }


}
